package com.erbadagang.springboot.rsa.controller;

import com.erbadagang.springboot.rsa.util.AesUtils;
import com.erbadagang.springboot.rsa.util.RsaGenerator;
import com.erbadagang.springboot.rsa.util.RsaUtils;
import org.apache.commons.codec.binary.Base64;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

/**
 * RsaController作用是：通过controller来生成公私钥对，加密及解密。
 *
 * @ClassName: RsaController
 * @author: 郭秀志 jbcode@126.com
 * @date: 2020/7/25 11:09
 * @Copyright:
 */
@RestController
@RequestMapping("rsa")
public class RsaController {

    /**
     * 获取RSA加密形式的publicKey和privateKey
     */
    @GetMapping("/genKey")
    public Map<String, String> getRsaKey() throws NoSuchAlgorithmException {
        RsaGenerator rsaGenerator = new RsaGenerator();
        rsaGenerator.generateKeyPair();
        Map<String, String> map = new HashMap<>(4);
        map.put("privateKey", Base64.encodeBase64String(rsaGenerator.getPrivateKey().getEncoded()));
        map.put("publicKey", Base64.encodeBase64String(rsaGenerator.getPublicKey().getEncoded()));
        return map;
    }


    /**
     * 发送端逻辑：
     * 1.客户端随机产生AES的密钥；
     * 2.对重要信息进行AES加密；
     * 3.通过使用服务端RSA公钥对AES密钥进行加密。
     * 接收端逻辑：
     * 1.对加密后的AES密钥进行服务端RSA私钥解密，拿到密钥原文；
     * 2.对加密后的重要信息进行AES解密，拿到原始内容。
     */
    @GetMapping("/encryptDecryptSign")
    public void encryptDecryptSign() throws Exception {
        //发送方公私钥
        String sendPrivateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDKr3Zhb/aM7DHnhT0PN2Fb7hnQxCfjwkurtROSVNZhDvaxAiNhuC/wUIUDd9tAGQSgIgEag6ISaFMcRIMTADpN6QJyiUcVy2M4LmRO55VotmMB9g6OUBmsBju3TL58Iloy05j1x/T0PG9N0KegKDbIwG8/FQsKXm5kfDOV5piPPReveiykfv6kh8ZqCbSBtIVpgdPDD5r13Cj4+Q0xGabznGXv5gC0xhKyZr3ayGPGcUvB2eW3FAFn6qOLMKvbawnhDZPkiNdGU+yD6Uz27R5Fyy8s1wGK3Uk+yPA23mxVXsYu19a+8JINRV1acmYGGXsYJmAi445kNsgFVsO28TLdAgMBAAECggEAC6plqd4D1sCRbr3gccvCMsRVgAqKMTWxnURix/1SCWwPDskMuEcdmztHLJftapcGCSFr5tbEsUKH5gybbrCIqotKtMTp7nsyTr180H3Lv6cfs7ExzUcW8yu4rCginoprnplHKH5FvvjrfxMPUsx9urg4ruzLIeGlgOsVHP+UsEm9oqGSA1O7fzWQfJszuLRSVAu8GFYYzpGMm5FMVfgPHpZZUrZRcnJnMwQVNzwNh121zDmbx7Win/LKAD4C6s6g/KDKs7L1QYhiEBvmI0AkCcaLtdl3YhiZfNSbxRnJ364nnLFZSPvyvLl0zxFyPWIX61jYKSqu6uM3nogT5JnvgQKBgQDrxhDKwLCYmOd2QZ5EPK9/d+y1SOgwKxW243SAZobRIVTUkJW3NzJe5lxisbMEDsxRyUKHm0aL49bNkQeklBmnMAmtSG5MMgTz/fqRjN7o9+bWukdOwFVRNfDJ/dbHKCDr+dwCiHDyu/qkcCfjIBUR+mS1z2x3LWUIxwb0MQkuVQKBgQDcErrH5zeJ86obWDhhEstD0JgYf/pGXpGQadEcuOall0Uhc/hRlTSTH7QC+k3J5zQ8WdG78vxEAAuPMC7JU7Nm0GKw0xmp/nq0nwvmF+psAw+uNNtbIn1o3uUjqdt27Sv7rS512mKX8S1Mj7y2jtn45lLv9VeYDsSL0O2k2wZqaQKBgQChYhq+XbTDTu4oQPQPKybJbpIE6Jmd1u/vFrP467TeUx1YvnrsRQjicnXMTGwHnAV4+fTjE4LvYA34+YusuH7ytGv7Q3fUCezgAfnQRQeTmZRVaH5Exlvf0bc229x2x935CDbzOOdvDwKaKfbzfVNO0gC7ffZ1gQoGPw1gemwZXQKBgQDEED+tpxX45kevsuoPueGzmhxW/3VmygvfYBa4AxchgeJKCnq5nDdJt931JTC2ZzBHcDIFw1Xx8yRZPjEAlnxnZdH2/SuJIroJPwUnyjjEX/nRVy/yQoj+LE5ydnqaunQL9d9Fifl6qpiT9B7Jef1B3VkYhTiztLxwYAPIcoWFuQKBgFulQsCQYESMeT59Vf9cSUTlVs/Hen2TsKeHhaqhx3SyRsHLvDnTz5JxL/5GZS8dCb+VZdCxcMYtfaFfY2wzVBDRj7wOFLf6RuQ5mSwHpapRv2XV4pImVRAjktFQsHAyN7fflhpVy/cGWw7tovJPjmIDNGIq8hdiIdo6CfepGoTB";
        String sendPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyq92YW/2jOwx54U9DzdhW+4Z0MQn48JLq7UTklTWYQ72sQIjYbgv8FCFA3fbQBkEoCIBGoOiEmhTHESDEwA6TekCcolHFctjOC5kTueVaLZjAfYOjlAZrAY7t0y+fCJaMtOY9cf09DxvTdCnoCg2yMBvPxULCl5uZHwzleaYjz0Xr3ospH7+pIfGagm0gbSFaYHTww+a9dwo+PkNMRmm85xl7+YAtMYSsma92shjxnFLwdnltxQBZ+qjizCr22sJ4Q2T5IjXRlPsg+lM9u0eRcsvLNcBit1JPsjwNt5sVV7GLtfWvvCSDUVdWnJmBhl7GCZgIuOOZDbIBVbDtvEy3QIDAQAB";

        //接收方公私钥
        String recPrivateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCP3no8bYUMsdW1sSsIaUxaWDxxOBlDYNCuoVn7BlyptCnIOkqu86dVCB0dRxG90KlZoCtXhfYQgZkIkzUYdAeQsIHJr2PZn+z8XuqQllqDXDbBi0VXIx0JS8pjNP9pe/3iyLOWK7UPZkew1+OaomKnjpjFAYUxBlakFloP02mmaOfCHxkHzLWQRw/uBD7WCmCtKP5Mism78s5QuZxyfbMopECloVU8YzYc6tm5nygPOvudIxZtCJDNRTmgXtDra/WnvWE/+hVBjvCO1uPxLI5krPwdlYuBzlrylmuCoVZr9K5mJcMLt4SH2ApWLx/hyWJbyB1FZlhM4DzGIw2oRnnVAgMBAAECggEAfmAPP8V0ehI8h71474qPZ0zayxlcF7OTm9JgGAEepHN9wER0Ffoxop/d8znae8IvAGuRpvAllZpBsyacHT7O5moll+RY8XFp2sYFhbyNBZabAqgz4LcXanMI9Nw4/4/LFMr39ZGvGjfeAZmidNLvlf/MckFDnizTLo/zzLMIuwNW7ZNAYCokNa+/MwmTly6d1fuoazYNvv+4u7GVkEU9pNDwqeQP0JRY1O5uN+7RLfH7IZ3ObuKIvoJOIZCzEgSqA0DTvqgRkNHm3L5oRkVXyv85rO55n3EFwZ6boe1KaHRGX0WHTpkGWcto9Sz3tmKIexBCeveV+XjwRya5RJrcAQKBgQDdikiTSYmXMREdQfab4+BXrK4Wv5c0l+DdfGczdn4/wl5TMV7nEXh9zOSgET1Wxt6yULFQalofHQzZym5VENsEe2kjSEWf39m4Y+wRHjhsG89wSDEGL+dYVsS74Np0doREVzOssXSltfV2iOAwBgublMQJ41hLcC7ypMZugtKz+QKBgQCmP1WtgFB5uugEKaqQul9N/17g1PZ1vbIRAoYhinbsBrlhc+H6YonFXPECIcc84Hds7dhxkcLUlUawybTo/JzpvQBTB823TH1U/VuA+uE3ajQv2lZC8hYWu4hpwndsdqePrmmXVJFT2aH12E9y5yaoVesvFPQ350x/NVLxfQUzvQKBgQCsW+XTEaeGhZo3FRb0efoUvDhFYpIVTQSZzSvNkibvHB2exA59383Ksho9nqwGU3r3aGhLlDLBeiyBVUk5zX9YoVtPI+9nTxVoq/UB7G0hTxG43bGmiqaGyBsPwQS1D3Aga2e8t+N0+Xgb3KnvMwTc6oUK3GHZb1JXXXM0j3u2oQKBgCHeDy88T6is2e1XK6c2QIocNxDocZkE3wy2DesxUQ6+Q+/FcsjWYCizyWlcxkDxnYK0ZX6laiJykqcbQF6ib7jyRumjUlZAH9w7jPOWqGDoot8IxL/4n2VcKOsasceH2JTdvCcXFFAXqvXxbiYDTw3GCxZZV3M4DI5xp4cIqBGlAoGAUHdGKaCauzdUrXB8wV9symBQvrEbmAXlHI713CpDPBHjYZ+STvYbMncSxI2IXELZkE0UHYQYqDgc+h+1n+r5lgi+ljBcFAiZBlU4cdrdzkEvJ6/OMqyAlko5+0hOr1tgkuPU1jQe33JuOaKvzqtGjmV8hkxh2wH0FSGBfLLd4IE=";
        String recPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj956PG2FDLHVtbErCGlMWlg8cTgZQ2DQrqFZ+wZcqbQpyDpKrvOnVQgdHUcRvdCpWaArV4X2EIGZCJM1GHQHkLCBya9j2Z/s/F7qkJZag1w2wYtFVyMdCUvKYzT/aXv94sizliu1D2ZHsNfjmqJip46YxQGFMQZWpBZaD9Nppmjnwh8ZB8y1kEcP7gQ+1gpgrSj+TIrJu/LOULmccn2zKKRApaFVPGM2HOrZuZ8oDzr7nSMWbQiQzUU5oF7Q62v1p71hP/oVQY7wjtbj8SyOZKz8HZWLgc5a8pZrgqFWa/SuZiXDC7eEh9gKVi8f4cliW8gdRWZYTOA8xiMNqEZ51QIDAQAB";

//        String AesKey =RandomStringUtils.randomAlphanumeric(16);

        //输入的明文参数
        String inputJson = "{\"name\": \"guo\",\"age\": 40}";

        /**
         * 发送端业务开始
         */
        byte[] aesKey = AesUtils.generateAesKey(128);
        // AES 对称加密业务数据
        String encryptData = AesUtils.encrypt(inputJson, aesKey);//注意key为16位
        System.out.println("encryptData = " + encryptData);
        // RSA 私钥签名数据
        String signature = RsaUtils.sign(inputJson, sendPrivateKey);
        // RSA 公钥加密AES密钥传送给接收方
        String encryptAesKey = RsaUtils.encrypt(aesKey, recPublicKey);

        /**
         * 接收端业务开始
         */
        byte[] decryptedData;
        boolean signChecked;
        // 使用"接收端RSA私钥"进行【非对称解密操作】发送端的“AES对称加密Key”
        byte[] encryptKeyByte = RsaUtils.decrypt(encryptAesKey, recPrivateKey);
        System.out.println("encryptAesKey = " + Base64.encodeBase64String(encryptKeyByte));
        // 使用对称加密AES Key对发送端对称加密后的业务数据内容，进行【对称解密操作】，获取解密后的数据内容。
        decryptedData = AesUtils.decrypt(encryptData, encryptKeyByte);
        System.out.println("decryptedData解密后的业务数据 = " + new String(decryptedData));
        // 使用“发送端RSA公钥”对发送端使用“RSA私钥进”行非对称加密签名后的数据进行【非对称解密验签操作】，判断数据完整性。
        signChecked = RsaUtils.checkSign(decryptedData, signature, sendPublicKey);
        System.out.println("signChecked = " + signChecked);
    }
}
